package com.deyou.activity;

import android.content.Context;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Base64;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps2d.AMap;
import com.amap.api.maps2d.CameraUpdateFactory;
import com.amap.api.maps2d.LocationSource;
import com.amap.api.maps2d.MapView;
import com.amap.api.maps2d.model.BitmapDescriptorFactory;
import com.amap.api.maps2d.model.Marker;
import com.amap.api.maps2d.model.MarkerOptions;
import com.amap.api.maps2d.model.MyLocationStyle;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.geocoder.GeocodeAddress;
import com.amap.api.services.geocoder.GeocodeQuery;
import com.amap.api.services.geocoder.GeocodeResult;
import com.amap.api.services.geocoder.GeocodeSearch;
import com.amap.api.services.geocoder.RegeocodeResult;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.deyou.Constants;
import com.deyou.R;
import com.deyou.adapter.CityAdapter;
import com.deyou.base.BaseActivity;
import com.deyou.callback.ServerApi;
import com.deyou.model.CityBean;
import com.deyou.model.CollectionBean;
import com.deyou.model.HouseResourceAttrBean;
import com.deyou.model.LzyResponse;
import com.deyou.util.AESUtil;
import com.deyou.util.AMapUtil;
import com.deyou.util.AndroidUtils;
import com.deyou.util.Logger;
import com.deyou.util.SPUtils;
import com.deyou.util.Urls;
import com.google.gson.reflect.TypeToken;

import org.json.JSONException;
import org.json.JSONObject;

import java.lang.reflect.Type;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function;

public class HouseLocationActivity extends BaseActivity implements AMapLocationListener, LocationSource, GeocodeSearch.OnGeocodeSearchListener, BaseQuickAdapter.OnItemClickListener {

    @BindView(R.id.tv_mid_title)
    TextView tvMidTitle;
    @BindView(R.id.edt_city)
    EditText edtCity;
    @BindView(R.id.iv_clear_city)
    ImageView ivClearCity;
    @BindView(R.id.edt_address)
    EditText edtAddress;
    @BindView(R.id.amap_view)
    MapView amapView;
    @BindView(R.id.city_recycler_view)
    RecyclerView cityRecyclerView;

    private AMap aMap;
    private Marker geoMarker;
    private GeocodeSearch geocoderSearch;
    private OnLocationChangedListener mListener;
    private AMapLocationClient mlocationClient;
    private AMapLocationClientOption mLocationOption;
    private CityAdapter mCityAdapter;

    private static final int STROKE_COLOR = Color.argb(180, 3, 145, 255);
    private static final int FILL_COLOR = Color.argb(10, 0, 0, 180);
    private float lon, lat;
    private List<CityBean> mCityList = new ArrayList<>();
    private InputMethodManager imm;
    private HouseResourceAttrBean houseCityCodeBean;
    private String cityName;
    private String regionId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_house_location);
        ButterKnife.bind(this);
        //在activity执行onCreate时执行amapView.onCreate(savedInstanceState)，创建地图
        amapView.onCreate(savedInstanceState);
        houseCityCodeBean = (HouseResourceAttrBean) getIntent().getExtras().getSerializable("houseTypeAttr");
        initView();
        initListener();
    }

    private void initView() {
        imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        tvMidTitle.setText("位置");
        cityRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        cityRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.HORIZONTAL));
        mCityAdapter = new CityAdapter(this);
        if (aMap == null) {
            aMap = amapView.getMap();
            geoMarker = aMap.addMarker(new MarkerOptions().anchor(0.5f, 0.5f).icon(BitmapDescriptorFactory.fromResource(R.drawable.gps_point)));
//            setUpMap();
        }
        geocoderSearch = new GeocodeSearch(this);
        geocoderSearch.setOnGeocodeSearchListener(this);
    }

    private void initListener() {
        mCityAdapter.setOnItemClickListener(this);
        edtAddress.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    getLatlon();
                }
                return false;
            }
        });

        edtCity.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                    getCityByKeyWord(edtCity.getText().toString());
                }
                return false;
            }
        });
    }

    /**
     * 设置一些amap的属性
     */
    private void setUpMap() {
        aMap.setLocationSource(this);// 设置定位监听
        aMap.getUiSettings().setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
        aMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
        setupLocationStyle();
    }

    private void setupLocationStyle() {
        // 自定义系统定位蓝点
        MyLocationStyle myLocationStyle = new MyLocationStyle();
        // 自定义定位蓝点图标
        myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.gps_point));
//        // 自定义精度范围的圆形边框颜色
//        myLocationStyle.strokeColor(STROKE_COLOR);
//        //自定义精度范围的圆形边框宽度
//        myLocationStyle.strokeWidth(5);
//        // 设置圆形的填充颜色
        myLocationStyle.radiusFillColor(FILL_COLOR);
        //定位一次，且将视角移动到地图中心点。
        myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE);
        // 将自定义的 myLocationStyle 对象添加到地图上
        aMap.setMyLocationStyle(myLocationStyle);
    }

    @Override
    protected boolean translucentStatusBar() {
        return super.translucentStatusBar();
    }

    @OnClick({R.id.iv_left_back, R.id.iv_clear_city, R.id.btn_bottom})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.iv_left_back:
                finish();
                break;
            case R.id.iv_clear_city:
                edtCity.setText("");
                edtAddress.setText("");
                break;
            case R.id.btn_bottom:
                if (TextUtils.isEmpty(edtCity.getText().toString())) {
                    showToast("请选择城市");
                    return;
                }
                if (TextUtils.isEmpty(edtAddress.getText().toString())) {
                    showToast("请填写具体地址");
                    return;
                }
                houseCityCodeBean.resourceLatitude = lat;
                houseCityCodeBean.resourceLongitude = lon;
                houseCityCodeBean.resourceRegion = regionId;
                houseCityCodeBean.resourceAddress = edtAddress.getText().toString();
                Bundle bundle = new Bundle();
                bundle.putSerializable("houseLocation", houseCityCodeBean);
                AndroidUtils.startNextActivity(HouseLocationActivity.this, RoomAndBedActivity.class, bundle, false);
                break;
        }
    }

    /**
     * 响应地理编码
     */
    public void getLatlon() {
        showLoading("正在获取地址");
//        GeocodeQuery query = new GeocodeQuery("泰和路2038号", "上海市");// 第一个参数表示地址，第二个参数表示查询城市，中文或者中文全拼，citycode、adcode，
        GeocodeQuery query = new GeocodeQuery(edtAddress.getText().toString(), TextUtils.isEmpty(cityName) ? edtCity.getText().toString() : cityName);// 第一个参数表示地址，第二个参数表示查询城市，中文或者中文全拼，citycode、adcode，
        geocoderSearch.getFromLocationNameAsyn(query);// 设置同步地理编码请求
    }

    @Override
    protected void onPause() {
        super.onPause();
        //在activity执行onPause时执行mMapView.onPause ()，暂停地图的绘制
        amapView.onPause();
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        //在activity执行onSaveInstanceState时执行mMapView.onSaveInstanceState (outState)，保存地图当前的状态
        amapView.onSaveInstanceState(outState);
    }

    @Override
    protected void onResume() {
        super.onResume();
        //在activity执行onResume时执行mMapView.onResume ()，重新绘制加载地图
        amapView.onResume();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //在activity执行onDestroy时执行mMapView.onDestroy()，销毁地图
        amapView.onDestroy();
    }

    /**
     * 定位成功后回调函数
     */
    @Override
    public void onLocationChanged(AMapLocation amapLocation) {
        if (mListener != null && amapLocation != null) {
            if (amapLocation != null
                    && amapLocation.getErrorCode() == 0) {
                mListener.onLocationChanged(amapLocation);// 显示系统小蓝点
                aMap.moveCamera(CameraUpdateFactory.zoomTo(18));
                edtCity.setText(amapLocation.getCity() + amapLocation.getDistrict());
                edtAddress.setText(amapLocation.getStreet() + amapLocation.getStreetNum());
                edtCity.setSelection(edtCity.getText().length());
                edtAddress.setSelection(edtAddress.getText().length());
                lon = (float) amapLocation.getLongitude();
                lat = (float) amapLocation.getLatitude();
                Logger.i(Logger.LOGTAG + "AmpLocation", amapLocation.toString());
            } else {
                String errText = "定位失败," + amapLocation.getErrorCode() + ": " + amapLocation.getErrorInfo();
                Logger.e(Logger.LOGTAG + "AmapErr", errText);
            }
        }
    }

    /**
     * 激活定位
     */
    @Override
    public void activate(OnLocationChangedListener listener) {
        mListener = listener;
        if (mlocationClient == null) {
            mlocationClient = new AMapLocationClient(this);
            mLocationOption = new AMapLocationClientOption();
            //设置定位监听
            mlocationClient.setLocationListener(this);
            //设置为高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //获取最近3s内精度最高的一次定位结果：
            //设置setOnceLocationLatest(boolean b)接口为true，启动定位时SDK会返回最近3s内精度最高的一次定位结果。如果设置其为true，setOnceLocation(boolean b)接口也会被设置为true，反之不会，默认为false。
            mLocationOption.setOnceLocationLatest(true);
            //设置定位参数
            mlocationClient.setLocationOption(mLocationOption);
            // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
            // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用stopLocation()方法来取消定位请求
            // 在定位结束后，在合适的生命周期调用onDestroy()方法
            // 在单次定位情况下，定位无论成功与否，都无需调用stopLocation()方法移除请求，定位sdk内部会移除
            mlocationClient.startLocation();
        }
    }

    /**
     * 停止定位
     */
    @Override
    public void deactivate() {
        mListener = null;
        if (mlocationClient != null) {
            mlocationClient.stopLocation();
            mlocationClient.onDestroy();
        }
        mlocationClient = null;
    }

    @Override
    public void onRegeocodeSearched(RegeocodeResult result, int rCode) {

    }

    @Override
    public void onGeocodeSearched(GeocodeResult result, int rCode) {
        dismissLoading();
        if (rCode == AMapException.CODE_AMAP_SUCCESS) {
            if (result != null && result.getGeocodeAddressList() != null
                    && result.getGeocodeAddressList().size() > 0) {
                GeocodeAddress address = result.getGeocodeAddressList().get(0);
                aMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                        AMapUtil.convertToLatLng(address.getLatLonPoint()), 18));
                geoMarker.setPosition(AMapUtil.convertToLatLng(address
                        .getLatLonPoint()));
                lon = (float) address.getLatLonPoint().getLongitude();
                lat = (float) address.getLatLonPoint().getLatitude();
            } else {
                showToast("对不起，没有搜索到相关数据！");
            }
        } else {
            AMapUtil.showerror(this, rCode);
        }
    }

    private void getCityByKeyWord(String keyword) {
        JSONObject object = new JSONObject();
        try {
            object.put("keywords", URLEncoder.encode(keyword, "UTF-8"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        String paramJson = object.toString();

        Type type = new TypeToken<LzyResponse<List<CityBean>>>() {
        }.getType();
        ServerApi.<LzyResponse<List<CityBean>>>getData(type, Urls.getCityList, "aaa", AESUtil.encrypt(paramJson))//
                .doOnSubscribe(new Consumer<Disposable>() {
                    @Override
                    public void accept(@NonNull Disposable disposable) throws Exception {
                        showLoading("城市查询中...");
                    }
                })//
                .map(new Function<LzyResponse<List<CityBean>>, List<CityBean>>() {
                    @Override
                    public List<CityBean> apply(@NonNull LzyResponse<List<CityBean>> response) throws Exception {
                        return response.data;
                    }
                })//
                .observeOn(AndroidSchedulers.mainThread())//
                .subscribe(new Observer<List<CityBean>>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        addDisposable(d);
                    }

                    @Override
                    public void onNext(@NonNull List<CityBean> cityList) {
                        if (null != cityList && cityList.size() > 0) {
                            mCityList = cityList;
                            handler.sendEmptyMessage(1);
                        } else {
                            handler.sendEmptyMessage(2);
                        }
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        e.printStackTrace();            //请求失败
                        handler.sendEmptyMessage(2);
                    }

                    @Override
                    public void onComplete() {
                        dismissLoading();
                    }
                });
    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 1:
                    mCityAdapter.addData(mCityList);
                    cityRecyclerView.setAdapter(mCityAdapter);
                    cityRecyclerView.setVisibility(View.VISIBLE);
                    break;
                case 2:// 没有数据
                    cityRecyclerView.setVisibility(View.GONE);
                    break;

            }
        }
    };

    @Override
    public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
        if (null != mCityList.get(position)) {
            edtCity.setText(mCityList.get(position).regionName);
            cityName = mCityList.get(position).cityName;
            regionId = mCityList.get(position).regionId;
            handler.sendEmptyMessage(2);
        }
    }
}
